﻿using Miao;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using UnityEngine;
using static UnityEditor.Progress;


/// <summary>
/// 泛型DefDatabase会存储所有基于T的Def类别
/// 读取mod时间会缓慢，但生成不会
/// </summary>
/// <typeparam name="T"></typeparam>
public static class DefDatabase<T> where T : Def
{
    private static List<T> defsList = new List<T>();

    private static Dictionary<string, T> defsByName = new Dictionary<string, T>();

    public static List<T> AllDefsListForReading => defsList;

    /// <summary>
    /// 反射调用
    /// </summary>
    public static void AddAllInMods()
    {
        HashSet<string> hashSet = new HashSet<string>();

        
        foreach (ModContentPack modPacks in LoadedModManager.RunningMods.OrderBy((m)=>m.OverwritePriority))
        {
            hashSet.Clear();

            foreach (T def in modPacks.AllDefs.OfType<T>())
            {
                if (!hashSet.Add(def.defName))
                {
                    Log.Error(string.Concat("Mod ", modPacks, " has multiple ", typeof(T), "s named ", def.defName, ". Skipping."));
                }
                else
                {
                    Add(def);
                }
            }
        }
    }



    public static void Clear()
    {
        defsList.Clear();
        defsByName.Clear();
    }


    public static void Add(T def)
    {
        try
        {
            defsList.Add(def);
            defsByName.Add(def.defName, def);
        }catch
        (Exception e)
        {
            Debug.LogException(e);
        }
    }
    private static void Remove(T def)
    {
        defsByName.Remove(def.defName);
        defsList.Remove(def);
    }


    public static T GetNamed(string defName, bool errorOnFail = true)
    {
        if (errorOnFail)
        {
            if (defsByName.TryGetValue(defName, out var value))
            {
                return value;
            }
            Log.Error(string.Concat("Failed to find ", typeof(T), " named ", defName, ". There are ", defsList.Count, " defs of this type loaded."));
            return null;
        }
        if (defsByName.TryGetValue(defName, out var value2))
        {
            return value2;
        }
        return null;
    }

    public static T GetNamedSilentFail(string defName)
    {
        return GetNamed(defName, errorOnFail: false);
    }


    public static T GetRandom()
    {
        return defsList.Random();
    }
}

